package com.ruoyi.consumer.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.SelectRoomTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.consumer.domain.UserRoomRel;
import com.ruoyi.consumer.domain.VRoomHy;
import com.ruoyi.consumer.domain.query.VRoomHyQuery;
import com.ruoyi.consumer.domain.vo.HeatingLocationVo;
import com.ruoyi.consumer.domain.vo.HeatingRegionVo;
import com.ruoyi.consumer.mapper.UserRoomRelMapper;
import com.ruoyi.consumer.mapper.VRoomHyMapper;
import com.ruoyi.consumer.service.IVRoomHyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 供热用户
 * @author lisongtao
 * @date 2023/10/21 23:27
 */
@Service("vRoomHyService")
public class VRoomHyServiceImpl implements IVRoomHyService {

    /**
     * 供热用户redis存储key
     */
    private static final String HEAT_USER_LOCATION_KEY = "heat:user:location";

    @Autowired
    private VRoomHyMapper vRoomHyMapper;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserRoomRelMapper userRoomRelMapper;

    /**
     * 项目预加载，加载生成小区级联查询信息
     */
    @PostConstruct
    public void init() {
        refreshHeatingLocationCache();
    }

    /**
     * 获取所有的小区信息
     */
    @Override
    public List<String> selectFParentList() {
        List<HeatingLocationVo> locationVos = redisCache.getCacheList(HEAT_USER_LOCATION_KEY);
        if (CollUtil.isNotEmpty(locationVos)) {
            return locationVos.stream().map(HeatingLocationVo::getName).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 根据小区名称查询供热楼座/区域名称
     *
     * @param FParent
     */
    @Override
    public List<String> selectRegionList(String FParent) {
        if (StringUtils.isBlank(FParent)) {
            throw new ServiceException("小区名称不能为空！");
        }
        List<HeatingLocationVo> locationVos = redisCache.getCacheList(HEAT_USER_LOCATION_KEY);
        Optional<HeatingLocationVo> first = locationVos.stream().filter(heatingLocationVo -> FParent.equals(heatingLocationVo.getName())).findFirst();
        return first.map(heatingLocationVo -> heatingLocationVo.getRegionLists().stream().map(HeatingRegionVo::getRegion).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList())).orElseGet(ArrayList::new);
    }

    /**
     * 查询单元和房间信息
     * @param FParent 小区名称
     * @param region  楼座/区域名称
     */
    @Override
    public HeatingRegionVo selectUnitAndRoomList(String FParent, String region) {
        if (StringUtils.isBlank(FParent)) {
            throw new ServiceException("小区名称不能为空！");
        }
        if (StringUtils.isBlank(region)) {
            throw new ServiceException("楼座/区域名称不能为空！");
        }
        List<HeatingLocationVo> locationVos = redisCache.getCacheList(HEAT_USER_LOCATION_KEY);
        Optional<HeatingLocationVo> first = locationVos.stream().filter(heatingLocationVo -> FParent.equals(heatingLocationVo.getName())).findFirst();
        boolean present = first.isPresent();
        if (!present) {
            throw new ServiceException("当前小区不存在！");
        }
        HeatingLocationVo heatingLocationVo = first.get();
        List<HeatingRegionVo> regionLists = heatingLocationVo.getRegionLists();
        Optional<HeatingRegionVo> existRegion = regionLists.stream().filter(heatingRegionVo -> region.equals(heatingRegionVo.getRegion())).findFirst();
        if (!existRegion.isPresent()) {
            throw new ServiceException("当前单元在小区中不存在！");
        }
        return existRegion.get();
    }

    /**
     * 查询供热用户信息
     *
     * @param vRoomHyQuery
     * @return
     * @author lisongtao
     * @date 2023/10/22 21:39
     */
    @Override
    public VRoomHy queryInformationHeatUser(VRoomHyQuery vRoomHyQuery) {
        String selectType = vRoomHyQuery.getSelectType();
        SelectRoomTypeEnum roomTypeEnum = SelectRoomTypeEnum.getSelectRoomTypeEnum(selectType);
        if (roomTypeEnum == null) {
            throw new ServiceException("不支持当前查询方式！");
        }

        // 供热编号模式查询限制条件判断
        if (SelectRoomTypeEnum.HEAT_NUMBER.equals(roomTypeEnum)) {
            String cardNo = vRoomHyQuery.getCardNo();
            String ower = vRoomHyQuery.getOwer();
            if (StringUtils.isBlank(cardNo) || StringUtils.isBlank(ower)) {
                throw new ServiceException("供热号查询中，供热卡号和用户名均不能为空！");
            }
        }

        // 查询符合条件的供热用户
        List<VRoomHy> vRoomHies = vRoomHyMapper.queryInformationHeatUser(vRoomHyQuery);
        if (CollUtil.isEmpty(vRoomHies)) {
            throw new ServiceException("查询失败，未查询到供热用户！");
        }
        if (vRoomHies.size() > 1) {
            throw new ServiceException("查询失败，当前信息查询出多个供热用户，请正确输入查询条件！");
        }
        return vRoomHies.get(0);
    }


    /**
     * 绑定供热用户
     *
     * @param vRoomHyQuery 供热用户查询条件
     * @return
     * @author lisongtao
     * @date 2023/10/22 21:45
     */
    @Override
    public void boundHeatUser(VRoomHyQuery vRoomHyQuery) {
        VRoomHy vRoomHy = queryInformationHeatUser(vRoomHyQuery);
        if (vRoomHy == null || StringUtils.isBlank(vRoomHy.getCardNo())) {
            throw new ServiceException("查询供热用户信息失败！");
        }
        Long userId = SecurityUtils.getUserId();
        UserRoomRel queryRel = new UserRoomRel();
        queryRel.setUserId(userId);
        queryRel.setHeatNumber(vRoomHy.getCardNo());
        int num = userRoomRelMapper.countUserRoomRelList(queryRel);
        if (num > 0) {
            throw new ServiceException("当前用户已绑定此房产！");
        }
        UserRoomRel userRoomRel = new UserRoomRel();
        userRoomRel.setId(IdUtil.getSnowflakeNextId());
        userRoomRel.setUserId(userId);
        userRoomRel.setHeatNumber(vRoomHy.getCardNo());
        userRoomRel.setHomeOwner(vRoomHy.getOwer());
        userRoomRel.setLocationName(vRoomHy.getParent());
        userRoomRel.setRegionName(vRoomHy.getRegion());
        userRoomRel.setUnitName(vRoomHy.getUnit());
        userRoomRel.setRoomName(vRoomHy.getRoom());
        userRoomRel.setRoomId(vRoomHy.getRoomID());
        userRoomRel.setContactNumber(vRoomHy.getTelNo());
        userRoomRel.setCreateTime(new Date());
        userRoomRel.setCreateBy(SecurityUtils.getUsername());
        num = userRoomRelMapper.insertUserRoomRel(userRoomRel);
        if (num < 1) {
            throw new ServiceException("绑定供热用户失败！");
        }
    }


    /**
     * 刷新供热地区
     */
    @Override
    public void refreshHeatingLocationCache() {
        // 查询出所有的
        List<VRoomHy> vRoomHies = vRoomHyMapper.selectVRoomHyVos(new VRoomHyQuery());
        List<String> allFParents = vRoomHies.stream().map(VRoomHy::getParent).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());

        // 查询遍历 生成缓存实体
        List<HeatingLocationVo> locationVos = new ArrayList<>();
        for (String fParent : allFParents) {
            HeatingLocationVo heatingLocationVo = new HeatingLocationVo();
            heatingLocationVo.setName(fParent);
            List<String> allRegions = vRoomHies.stream().filter(vRoomHy -> fParent.equals(vRoomHy.getParent()) && StringUtils.isNotBlank(vRoomHy.getRegion())).map(VRoomHy::getRegion).distinct().collect(Collectors.toList());
            List<HeatingRegionVo> regionVos = new ArrayList<>();
            for (String region : allRegions) {
                HeatingRegionVo heatingRegionVo = new HeatingRegionVo();
                heatingRegionVo.setRegion(region);
                List<String> unitLists = vRoomHies.stream().filter(vRoomHy -> fParent.equals(vRoomHy.getParent()) && region.equals(vRoomHy.getRegion()) && StringUtils.isNotBlank(vRoomHy.getUnit())).map(VRoomHy::getUnit).distinct().collect(Collectors.toList());
                List<String> roomLists = vRoomHies.stream().filter(vRoomHy -> fParent.equals(vRoomHy.getParent()) && region.equals(vRoomHy.getRegion()) && StringUtils.isNotBlank(vRoomHy.getRoom())).map(VRoomHy::getRoom).distinct().collect(Collectors.toList());
                heatingRegionVo.setRoomLists(roomLists);
                heatingRegionVo.setUnitLists(unitLists);
                regionVos.add(heatingRegionVo);
            }
            heatingLocationVo.setRegionLists(regionVos);
            locationVos.add(heatingLocationVo);
        }

        redisCache.deleteObject(HEAT_USER_LOCATION_KEY);
        // 将数据设置在缓存中
        redisCache.setCacheList(HEAT_USER_LOCATION_KEY, locationVos);
    }

}
